/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package Materials;

import Materials.MatteShader;
import Materials.ShinyPlasticShader;
import Raytracing.Shaders.Material;
import Raytracing.BRDF.BlendBRDF;
import Raytracing.BRDF.DiffuseBRDF;
import Raytracing.BRDF.LambertBRDF;
import Raytracing.BRDF.NullBRDF;
import Raytracing.BRDF.PhongBRDF;
import Raytracing.Shaders.CheckerTexture;
import Raytracing.Shaders.GridTexture;
import Raytracing.Shaders.Shader;
import Raytracing.Shaders.SolidTexture;
import processing.core.PApplet;
import processing.core.PImage;
import processing.core.PVector;

/**
 *
 * @author Matt
 */
public class MaterialFactory {

    // private final PFont fnt;
    public enum Materials {

        MATTE, TREE_GENERATOR, PLASTIC, GLASS, MIRROR, PHONG, GRID, BLACKSTRIPES, ROBOT_GENERATOR;
    }
    
    
    LambertBRDF grid = new LambertBRDF(new GridTexture());
    LambertBRDF checker = new LambertBRDF(new CheckerTexture(10, 10));
    //PolkaDots polka = new PolkaDots(this, 300);
    LambertBRDF grey = new LambertBRDF(new SolidTexture(new PVector(.4f, .4f, .5f)));
    LambertBRDF green = new LambertBRDF(new SolidTexture(new PVector(.2f, .8f, .2f)));
    LambertBRDF white = new LambertBRDF(new SolidTexture(new PVector(.8f, .8f, .8f)));
    LambertBRDF yellow = new LambertBRDF(new SolidTexture(new PVector(.8f, .8f, 0f)));
    DiffuseBRDF black = new DiffuseBRDF(new SolidTexture(new PVector(.1f, .1f, .1f)));
    //LambertBRDF walnutB = new LambertBRDF(new ImageTexture(walnut));
    PhongBRDF glossy = new PhongBRDF(new PVector(.2f, .1f, .1f), .75f, 500);
    PhongBRDF polished = new PhongBRDF(new PVector(.1f, .1f, .2f), .75f, 10000);
    //BlendBRDF wood = new BlendBRDF(walnutB, mirror, new SolidTexture(new PVector(.8f, 0, 0)));
    //BlendBRDF noise = new BlendBRDF(white, black, new Noise(this, 1, 1));
    // BlendBRDF whitePlastic = new BlendBRDF(grid, mirror, new SolidTexture(new PVector(.8f, 0, 0)));
    // BlendBRDF blend = new BlendBRDF(mirror, black, new CheckerTexture(10, 10));
    BlendBRDF gridBlend = new BlendBRDF(glossy, black, new GridTexture());
    BlendBRDF checkerVoid = new BlendBRDF(white, new NullBRDF(), new CheckerTexture(3, 3));
    // BlendBRDF woodStripes = new BlendBRDF(wood, black, new StripeProvider());

    public MaterialFactory(PApplet parent) {
        PImage walnut = parent.loadImage("floor.jpg");


        /*
        
        PGraphics pg = parent.createGraphics(600, 600, parent.JAVA2D);
        pg.smooth();
        
        pg.beginDraw();
        pg.background(250);
        pg.stroke(1);
        pg.fill(1);
        
        pg.textFont(fnt);
        Graphics2D pg2 = ((PGraphicsJava2D) pg).g2;
        
        pg2.setFont(new Font("SansSerif", Font.BOLD, 80));
        pg2.setColor(Color.black);
        
        for (int i = 0; i < 6; i++) {
        pg2.drawString(sceneBuffer.substring(i * 10, i * 10 + 10), 10, 100 * (i + 1));
        }
        pg2.setStroke(new BasicStroke(10.f));
        pg2.drawLine(0, 0, 600, 0);
        pg2.drawLine(0, 0, 0, 600);
        
        pg.endDraw();
         * */



    }

    public static Material getMaterial(Materials index) {

        switch (index) {
            case MATTE:
                return buildMatte("Matte", new PVector(.99f, .99f, .99f));
            /*
            case TREE_GENERATOR:
                return new TreeGenerator();
            
            case PLASTIC:
                return buildPlastic("Plastic", new PVector(.5f, .5f, .5f));
            case BLACKSTRIPES:
                BlackStripeShader shad = new BlackStripeShader("Black Stripes", .5f, new PVector(1f, 1f, 1f));
                shad.init();
                return shad;
            case MIRROR:
                return new Shader("Mirror", 1f, 0, 0, new SpecularReflectionBRDF(new FresnelDielectric(.177f, 3.6f), new PVector(.911f, .83f, .76f)));
            case GLASS:
                FresnelDielectric fd = new FresnelDielectric(1.0f, 1.1f);
                return new Shader("Glass", 4 / 7f, 0, 0, new SpecularReflectionBRDF(fd, new PVector(.9f, .9f, .9f)), new SpecularTransmissionBRDF(fd, new PVector(.5f, .5f, .8f)));
            case PHONG:
                return new Shader("Phong", 1, 1, 1, new PhongBRDF(new PVector(.01f, .01f, .01f), .4f, 5000));

            case GRID:
                return new Shader("Grid", 1, 1, 1, new LambertBRDF(new GridTexture()));
            case ROBOT:
                return new RoboGenerator();
                 
                 */
        }

        return null;
    }

    public static Shader buildMatte(String name, PVector color) {
        MatteShader shad = new MatteShader("Matte", color);
        shad.init();
        return shad;
    }

    public static Shader buildPlastic(String name, PVector color) {
        ShinyPlasticShader shad = new ShinyPlasticShader("Plastic", color);
        shad.init();
        return shad;
    }
}
